import cv2
import tensorflow as tf
from tensorflow import keras
import numpy as np
# 读取并处理图片
charList = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
            'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
            'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
def normalize_image(image):#归一化处理
    # 读取图像
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    # 将图像归一化
    gray=cv2.resize(gray,(28,28))
    normalized_image = gray / 255.0
    return normalized_image
def get_letter_regions(image):
    image = cv2.resize(image, (640, 480))
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    _, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
    # 寻找轮廓
    contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    letter_regions = []
    # 遍历轮廓并裁剪出字母区域
    contour_filter = 0
    for contour in contours:
        (x, y, w, h) = cv2.boundingRect(contour)
        # 根据实际情况调整裁剪参数，确保裁剪出字母区域
        if w > 100 and h > 100:
            # 将轮廓画出来
            #cv2.drawContours(image, [contour], -1, (0, 255, 0), 2)
            letter_regions.append(image[y:y + h, x:x + w])
            contour_filter += 1
    #print("轮廓数量：{},过滤后的数量：{}".format(len(contours),contour_filter))
    return letter_regions
def recognize_letter(image):
    image = normalize_image(image)  # 标准化图片和训练格式一样
    # 导入模型
    # 在处理图像时，一般使用四维的张量来表示，形状为（批次大小，高度，宽度，通道数）。
    image = np.reshape(image, (1, 28, 28, 1))
    # 预测图片
    predictions = model.predict(image)
    max_probability_index = np.argmax(predictions)
    max_probability = predictions[0][max_probability_index]
    if max_probability > 0.9:  # 预测结果大于90%
        max_probability_label = charList[max_probability_index]
        # 输出识别结果
        print("识别结果：{}，准确率：{:.2f}".format(max_probability_label, max_probability))


model = keras.models.load_model('CNN_model.h5')
cap = cv2.VideoCapture(0)
if cap.isOpened():
    print("相机打开成功！")
else:
    print("相机打开失败")
while True:
    # 读取视频流帧
    ret, frame = cap.read()
    if ret==None:
        print("打开摄像机失败！")
        break
    images = get_letter_regions(frame)  # 识别字母轮廓
    if len(images)==1:#当只识别到一个轮廓时
        letter_img=images[0]

        height, width, _ = letter_img.shape
        # 计算补全后的图片尺寸（取较大的一边作为边长）
        size = max(height, width)
        # 创建一张全白的正方形图片
        square_image = np.zeros((size, size, 3), dtype=np.uint8)
        square_image.fill(255)
        # 计算将长方形图片放在正方形图片中心的位置
        x = (size - width) // 2
        y = (size - height) // 2
        square_image[y:y+height, x:x+width] = letter_img
        recognize_letter(square_image)
        cv2.imshow("contour", square_image)
    #recognize_letter(frame)
    # 按下 'q' 键退出循环
    cv2.imshow("Output", frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
cap.release()
cv2.destroyAllWindows()